﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Web.Profile;
using System.Web.Security;

using HelfenHelfen.DataAccess.Interfaces;
using HelfenHelfen.DataAccess.Factories;
using HelfenHelfen.DataAccess.Entities;

// partially implementation based on the PetShop provider from codeplex.com
namespace HelfenHelfen.Web.Forms.Profile {
   public class ProfileProvider : System.Web.Profile.ProfileProvider {
      private static readonly IUserDetailDataAccess dal = DataAccessFactory.CreateUserDetailDataAccess();

      private const string ERR_INVALID_PARAMETER = "Invalid Profile parameter:";
      private static string applicationName = "HelfenHelfen";

      [DefaultValue("HelfenHelfen")]
      public override string ApplicationName { get; set;}

      public override void Initialize(string name, NameValueCollection config) {
         if (config == null)
            throw new ArgumentNullException("config");

         if (string.IsNullOrEmpty(config["description"])) {
            config.Remove("description");
            config.Add("description", "HelfenHelfen Custom Profile Provider");
         }

         if (string.IsNullOrEmpty(name))
            name = "HelfenHelfenProfileProvider";

         if (config["applicationName"] != null && !string.IsNullOrEmpty(config["applicationName"].Trim()))
            applicationName = config["applicationName"];

         base.Initialize(name, config);
      }

      public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection) {
         string username = (string)context["UserName"];
         bool isAuthenticated = (bool)context["IsAuthenticated"];
         MembershipUser userInfo = System.Web.Security.Membership.GetUser(username);
         UserDetail user = dal.Get((Guid) userInfo.ProviderUserKey);

         SettingsPropertyValueCollection svc = new SettingsPropertyValueCollection();
         foreach (SettingsProperty prop in collection) {
            SettingsPropertyValue pv = new SettingsPropertyValue(prop);

            if(user == null){
               pv.PropertyValue = string.Empty;
            }
            else{
               switch(pv.Property.Name){
                  case "FirstName":
                     pv.PropertyValue = user.FirstName;
                     break;

                  case "LastName":
                     pv.PropertyValue = user.Lastname;
                     break;

                  case "Street":
                     pv.PropertyValue = user.Street;
                     break;

                  case "PostalCode":
                     pv.PropertyValue = user.PostalCode;
                     break;

                  case "City":
                     pv.PropertyValue = user.City;
                     break;

                  case "CountryCode":
                     pv.PropertyValue = user.CountryCode;
                     break;

                  case "EMail":
                     pv.PropertyValue = user.EMail;
                     break;

                  case "PhoneNo":
                     pv.PropertyValue = user.PhoneNo;
                     break;

                  default:
                     throw new ApplicationException(ERR_INVALID_PARAMETER + " name.");
               }
            }

            svc.Add(pv);
         }
         return svc;
      }

      public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) {
         string username = (string)context["UserName"];
         bool isAuthenticated = (bool)context["IsAuthenticated"];
         MembershipUser userInfo = System.Web.Security.Membership.GetUser(username);
         Guid uniqueId = (Guid) userInfo.ProviderUserKey;
         UserDetail user = dal.GetOrCreate((Guid)userInfo.ProviderUserKey);

         // duplicate some information
         user.Username = username;
         user.EMail = userInfo.Email;

         foreach (SettingsPropertyValue pv in collection) {
            switch (pv.Property.Name) {
               case "FirstName":
                  user.FirstName = (string) pv.PropertyValue;
                  break;

               case "LastName":
                  user.Lastname = (string) pv.PropertyValue;
                  break;

               case "Street":
                  user.Street = (string) pv.PropertyValue;
                  break;

               case "PostalCode":
                  user.PostalCode = (string) pv.PropertyValue;
                  break;

               case "City":
                  user.City = (string) pv.PropertyValue;
                  break;

               case "CountryCode":
                  user.CountryCode = (string) pv.PropertyValue;
                  break;

               case "PhoneNo":
                  user.PhoneNo = (string) pv.PropertyValue;
                  break;

               default:
                  throw new ApplicationException(ERR_INVALID_PARAMETER + " name: " + pv.Property.Name);
            }
         }

         dal.Update(user);
      }

      public override int DeleteProfiles(ProfileInfoCollection profiles) {
         int deleteCount = 0;

         foreach (ProfileInfo p in profiles)
            if (DeleteProfile(p.UserName))
               deleteCount++;

         return deleteCount;
      }

      public override int DeleteProfiles(string[] usernames) {
         int deleteCount = 0;

         foreach (string user in usernames)
            if (DeleteProfile(user))
               deleteCount++;

         return deleteCount;
      }

      private static bool DeleteProfile(string username) {
         throw new NotImplementedException();
         return true; 
      }

      public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) {
         throw new NotImplementedException();

         string[] userArray = new string[0];
         return DeleteProfiles(userArray);
      }

      public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) {
         throw new NotImplementedException();
         return null;
      }

      public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) {
         throw new NotImplementedException();
         return null;
      }

      public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) {
         throw new NotImplementedException();
         return null;
      }

      public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) {
         throw new NotImplementedException();
         return null;
      }

      public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) {
         throw new NotImplementedException();
         return Int32.MaxValue;
      }
   }
}
